'''
Created on Aug 12, 2009

@author: Stanly
'''
import os, sys, random, pygame, constants
from objects import load_image
from pygame.constants import *
if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'

class MapRenderer(object):
    def __init__(self, map, screen, config):
        self.config = config
        random.seed(1)
        
        #constants
        self.display_w = int(self.config.display.width )
        self.display_h = int(self.config.display.height)
        self.resources_path = self.config.resources.path
        if self.config.display.enable_cells == 'yes': 
            self.enable_cells = True
        else:
            self.enable_cells = False
        print 'Draw cells: %s' % self.enable_cells
        
        #cell size and resources for map display
        self.cell_visible_left = 0
        self.cell_visible_top = 0
        self.viewport_w = ((self.display_w - constants.viewport_margin_w * 2) / constants.cell_width )
        self.viewport_h = ((self.display_h - constants.viewport_margin_h * 2 - constants.interface_controls_h) / constants.cell_height)
        
        print 'Display size %sx%s pixels' % (self.display_w, self.display_h)
        print 'Viewport size %sx%s cells' % (self.viewport_w, self.viewport_h)
        
        self.screen = screen
        
        self.map = map
        self.load_backgroud()
        self.move_map_center_to(self.map.active_system.star.x, self.map.active_system.star.y)
        
    def load_backgroud(self):
        self.background = pygame.Surface( (self.display_w, self.display_h) )
        self.background.fill(constants.background_color)
        self.background = self.background.convert()
    
    def draw_interface(self):
        #game map
        pygame.draw.rect(self.screen, constants.ui_color, 
                         pygame.Rect(1, 1, self.display_w - 2, self.display_h - constants.interface_controls_h - 2), 1)
        #controls
        pygame.draw.rect(self.screen, constants.ui_color, 
                         pygame.Rect(1, self.display_h - constants.interface_controls_h, self.display_w - 2, constants.interface_controls_h - 1), 1)
        
        #print information
        
        #system info
        system_info_text = 'Current system: %s. Planets: %s' % (self.map.active_system.name, len(self.map.active_system.planets))
        self.print_text(system_info_text, 10, self.display_h - constants.interface_controls_h + 10, 14)
        
        #mouse info
        mouse_x, mouse_y = pygame.mouse.get_pos()
        mouse_cell_x, mouse_cell_y = self.get_hovered_cell(mouse_x, mouse_y)
        mouse_info_text = 'Mouse coordinates %s:%s. Above cell %s:%s. Visible cells X axis: %s-%s, Y axis: %s-%s' \
            % (mouse_x, mouse_y, mouse_cell_x, mouse_cell_y, 
               self.cell_visible_left, self.cell_visible_left + self.viewport_w - 1,
               self.cell_visible_top, self.cell_visible_top + self.viewport_h - 1)
        self.print_text(mouse_info_text, 10, self.display_h - constants.interface_controls_h + 25, 14)
        
    def draw_cells(self):
        mouse_x, mouse_y = pygame.mouse.get_pos()
        mouse_cell_x, mouse_cell_y = self.get_hovered_cell(mouse_x, mouse_y)
        for cell_x in xrange(0, self.viewport_w):
            for cell_y in xrange(0, self.viewport_h):
                x = cell_x * constants.cell_width + constants.viewport_margin_h + 1
                y = cell_y * constants.cell_height + constants.viewport_margin_w + 1
                #draw hovered cell
                if mouse_cell_x == cell_x + self.cell_visible_left \
                and mouse_cell_y == cell_y + self.cell_visible_top:
                    pygame.draw.rect(self.screen, constants.ui_hover_color, pygame.Rect(x, y, constants.cell_width - 1, constants.cell_height - 1), 1)
                elif self.enable_cells:
                    pygame.draw.rect(self.screen, constants.ui_color, pygame.Rect(x, y, constants.cell_width - 1, constants.cell_height - 1), 1)
        
    def print_text(self, text, x, y, size, color = (0, 75, 0)):
        font = pygame.font.Font(os.path.join(self.resources_path, 'terminus.ttf'), size)
        text_surface = font.render(text, 1, color )
        clear_surface = pygame.Surface( (text_surface.get_width(), text_surface.get_height() ) )
        clear_surface.fill(constants.background_color)
        self.screen.blit(clear_surface, (x, y))
        self.screen.blit(text_surface, (x, y))
        
    def get_hovered_cell(self, mouse_x, mouse_y):
        mouse_cell_x = mouse_x / constants.cell_width + self.cell_visible_left
        #make sure that invisible cells are not hovered by mouse
        if mouse_cell_x > self.cell_visible_left + self.viewport_w - 1:
            return -1, -1
        mouse_cell_y = mouse_y / constants.cell_height + self.cell_visible_top
        if mouse_cell_y > self.cell_visible_top + self.viewport_h - 1:
            return -1, -1
            
        return mouse_cell_x, mouse_cell_y
    
    def loop(self):
        #draw initial background
        while 1:
            self.screen.blit(self.background, (0,0))
            #handle events, quit if True returned
            if self.handle_events():
                return
            
            self.draw_interface()
            self.map.active_system.update(self.cell_visible_left,
                                          self.cell_visible_top,
                                          self.viewport_w,
                                          self.viewport_h)
            
            self.map.active_system.visible_sprites.draw(self.screen)
            
            self.draw_cells()
            pygame.display.flip()
            
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == QUIT or ( event.type == KEYUP and event.key == 27):
                print 'Quiting!'
                return True
            #handle keyboard
            if event.type == KEYUP:
                if event.key == 273:
                    self.move_map_top(-1)
                if event.key == 274:
                    self.move_map_top(1)
                if event.key == 275:
                    self.move_map_left(1)
                if event.key == 276:
                    self.move_map_left(-1)
            
            return False
    
    def move_map_top(self, delta):
        self.cell_visible_top += delta
        if self.cell_visible_top < 0:
            self.cell_visible_top = 0
        if self.cell_visible_top + self.viewport_h > self.map.active_system.height:
            self.cell_visible_top = self.map.active_system.width - self.viewport_h
            
    def move_map_left(self, delta):
        self.cell_visible_left += delta
        if self.cell_visible_left < 0:
            self.cell_visible_left = 0
        if self.cell_visible_left + self.viewport_w > self.map.active_system.width:
            self.cell_visible_left = self.map.active_system.width - self.viewport_w
            
    def move_map_center_to(self, cell_x, cell_y):
        self.cell_visible_left = int(cell_x) - (self.viewport_w / 2)
        self.cell_visible_top = int(cell_y) - (self.viewport_h / 2)